package net.chathu.airgw 
{
	import flash.desktop.NativeApplication;
	import flash.desktop.Updater;
	import flash.errors.IOError;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.TimerEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.utils.ByteArray;
	import flash.utils.Timer;
	/**
	 * ...
	 * @author ze
	 */
	[Event(name = "applicationUpdate", type = "net.chathu.airgw.event.DataSendEvent")] 
	
	public class AutoUpdater extends EventDispatcher
	{
		
		private static var latest:URLLoader;
		private static var currentVersion:String;
		private static var latestVersion:String;
		
		private static var host:String = "http://airgateway.googlecode.com/files/"
		//private static var host:String = "http://localhost:8080/airgw/"
		//private static var host:String = "http://c6.gw.lt/airgw/"
		
		private static var updateFile:File;
		private static var fileName:String;
		
		private static var remoteStream:URLStream;
		private static var localStream:FileStream;
		
		private static var cbf:Function;
		private static var lastCheck:Date;
		
		public function AutoUpdater() 
		{
			
		}
		
		public static function check(cb:Function):void {
			if (lastCheck && (new Date().getTime() - lastCheck.getTime()) < 60000)
			{
				//Minimum check intervall: 1 perc;
				return;
			}
			
			Debug.echo("Checking version");
			//if (cb != null) 
			cbf = cb;
			
			//new Updater(); 
			
			latest = new URLLoader(new URLRequest(host+'airgw.latest.txt?r='+Math.random()))
			latest.addEventListener(Event.COMPLETE, onLatestLoadComplete);
			latest.addEventListener(IOErrorEvent.IO_ERROR, onError);
		}
		
		private static function onError(...e):void {
			trace("Update error");
			//can't update...
			if (cbf != null)
			{
				var t:Timer = new Timer(100,1)
				t.addEventListener(TimerEvent.TIMER, cbf)
				t.start()
			}
		}
		
		private static function onLatestLoadComplete(...e):void 
		{
			try {
				latestVersion = latest.data

				var appDesc:XML = NativeApplication.nativeApplication.applicationDescriptor;
				var ns:Namespace = appDesc.namespace();
				currentVersion = appDesc.ns::versionNumber;
				
				trace('remote : ' + latestVersion)
				trace('local  : ' + currentVersion)
				var latestVersionInfo:Array = latestVersion.split(".");
				var currentVersionInfo:Array = currentVersion.split(".");

				var needUpdate:Boolean = false;
				for (var i:int = 0; i < 3; i++)
				{
					var latest_i:String = latestVersionInfo[i];
					var current_i:String = currentVersionInfo[i];
					
					var len:int = Math.max(latest_i.length, current_i.length);
					latest_i = latest_i + "0000000".substr(0, len - latest_i.length);
					current_i = current_i + "0000000".substr(0, len - current_i.length);
					
					//trace("Padded: " + latest_i + " / " + current_i);
					if (parseInt(latest_i) > parseInt(current_i))
					{
						needUpdate = true;
						break;
					} else if (parseInt(current_i) >  parseInt(latest_i)) {
						//nem kell update(pl 0.6.3 a hivatalos legujabb verzio, de nekunk mar 0.7.1 van)
						break;
					}
				}

				//if (latestVersion > currentVersion)
				if (needUpdate)
				{
					Debug.echo("New version available: " + latestVersion);
					updateFile = File.applicationStorageDirectory.resolvePath(fileName = 'airgw.' + latestVersion + '.air');

					if (updateFile.exists) updateFile.deleteFile();
					Debug.echo('download update : ' + host + fileName);

					
					remoteStream = new URLStream();
					remoteStream.addEventListener(Event.COMPLETE, onUpdateDownloaded);
					remoteStream.addEventListener(ProgressEvent.PROGRESS, onUpdateDownloadProgress);
					remoteStream.addEventListener(IOErrorEvent.IO_ERROR, onError);
					remoteStream.load(new URLRequest(host + fileName));
				}
				else
				{
					Debug.echo("Your " + Config.PROGRAM_NAME + " is up-to-date!");
					trace('up to date..\n')
					if (cbf != null)
					{
						var t:Timer = new Timer(100,1)
						t.addEventListener(TimerEvent.TIMER, cbf)
						t.start()
					}
				}
			}catch (err:Error ) {
				onError(err);
			}
		}
		
		private static function onUpdateDownloaded(e:*):void
		{
			trace('done (' +remoteStream.bytesAvailable + ' bytes)')
			
			var buffer:ByteArray = new ByteArray();
			remoteStream.readBytes(buffer, 0, remoteStream.bytesAvailable);
			
			localStream = new FileStream();
			localStream.openAsync(updateFile, FileMode.WRITE);
			localStream.writeBytes(buffer, 0, buffer.length);
			
			Debug.echo('clean up');
			remoteStream.close();
			localStream.close();

			var updater:Updater = new Updater();
			try
			{
				Debug.echo('Stop application:');
				Main.onApplicationUpdate();
				Debug.echo('try to install update...');
				updater.update(updateFile, latestVersion.toString());
			}
			catch (e:Error)
			{
				Debug.echo('update Error '+e)
			}
		}		
		
		private static function onUpdateDownloadProgress(e:ProgressEvent):void
		{
			Debug.echo(int((e.bytesLoaded / e.bytesTotal)*100)+' %')
		}
		
	}

}